<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        let C = (...c) => console.log(c)
        C(1, 2, 3) // [1, 2, 3]
        // let arr=[1,2,3];
        // console.log(arr.length / 2);//1.5
        // console.log(arr[arr.length / 2]);//undefined
        // console.log(arr[(arr.length - 1) / 2]);//2
        console.log("------闭包------");
        // const fun=()=>{
        //     let count = 4;
        //     return ()=>{
        //         count++;
        //         console.log(count);
        //     }

        // }
        // let fun2=fun();
        // fun2();//5
        // fun2();//6
        console.log("------函数------");
        // 方式1：一个构造函数嘛，里面有个全局变量getName 指向一个匿名函数（小心闭包）
        function Foo() {
            getName = function () {
                console.log(1);
            };
            return this;
        }
        // 方式2：构造函数的一个属性getName 指向一个匿名函数  
        Foo.getName = function () {
            console.log(2);
        };
        // 方式3：构造函数的原型上有个getName方法 
        Foo.prototype.getName = function () {
            console.log('baidu' && 'google');
        };
        // 方式4：定义一个变量指针指向一个匿名函数  
        var getName = function () {
            console.log(4);
        };
        // 方式5：声明一个叫getName的有名函数 
        function getName() {
            console.log(5);
        }

        Foo.getName();//调用方式2 2
        getName();//4
        //当定义的变量和声明的函数重名了怎么办？答：它们都会进行预解析，
        //函数声明提前于变量声明，但是最终会被变量覆盖！so方式4获胜，输出结果为“4”！
        Foo().getName();//1
        //先执行方式1的“Foo()”,结果是"this" 并指向window，
        //并产生了一个全局getName(window.getName)指针指向一个匿名函数，然后再执行"this.getName()" , 
        //其实就是执行刚刚造出来的那个全局getName指向的匿名函数，所以输出“1”.
        getName();//1
        //句执行的是方式1执行出来的那个全局变量getName 指针指向的匿名函数，
        //有人问为啥不执行方式4？俺想说方式4已经被覆盖了！所以结果为 “1”.
        new Foo.getName();//2
        //  首先还是先看运算符优先级吧，我自个看完的结果是【new Foo() >  Foo() > new Foo】，
        //先运算方式2的Foo.getName() 结果为“2”，再new一个Foo实例对象。
        new Foo().getName();//goole
        // 先执行 new Foo(), 结果产生一个新的实例对象，​ 相当于(new Foo()).getName()
        //这个对象自己没有getName方法，所以就访问原型里的getName
        new new Foo().getName();//goole
        //这里可以看做new((new Foo()).getName())
        //可得 new(goole) 实例化返回值为goole



        console.log("------微任务 宏任务------");
        console.log('script start');

        setTimeout(function () {
            console.log('setTimeout');
        }, 0);

        Promise.resolve().then(function () {
            console.log('promise1');
        }).then(function () {
            console.log('promise2');
        });

        console.log('script end');

        // 结果如下：
        // script start
        // script end
        // promise1
        // promise2
        // setTimeout

    </script>
</body>

</html>